<!doctype html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<link rel="stylesheet" href="./../assets/css/combined.css">
	<link rel="shortcut icon" href="./../favicon.ico" />
	<script src="http://www.google.com/jsapi" type="text/javascript"></script>
	<script type="text/javascript">
		var path = './../';
	</script>
	<script src="./../assets/js/combined.js"></script>
	<title>Viewmodels - General - FuelPHP Documentation</title>
</head>
<body>
	<div id="container">
		<header id="header">
			<div class="table">
				<h1>
					<strong>FuelPHP, a PHP 5.3 Framework</strong>
					Documentation
				</h1>

				<form id="google_search">
					<p>
						<span id="search_clear">&nbsp;</span>
						<input type="submit" name="search_submit" id="search_submit" value="search" />
						<input type="text" value="" id="search_input" name="search_input" />
					</p>
				</form>
			</div>
			<nav>

				<div class="clear"></div>
			</nav>
			<a href="#" id="toc_handle">table of contents</a>
			<div class="clear"></div>
		</header>

		<div id="cse">
			<div id="cse_point"></div>
			<div id="cse_content"></div>
		</div>

		<div id="main">

			<article>
				<h2>Viewmodels</h2>

				<p>Viewmodels are optional. If you don't need them, you can use <a href="views.html">Views</a>.</p>

				<h3 id="what_is_a_viewmodel">What is a Viewmodel?</h3>

				<p>A Viewmodel is a class that contains the logic that is needed to generate your views. When the controller
				is done with your user input and is done with whatever actions it needed to take, it turns execution over to
				the Viewmodel to retrieve whatever data is needed for the view. A Viewmodel shouldn't do any data manipulation
				but can contain database calls and any other retrieval or preparation operations needed to generate the View's
				data.</p>

				<h3 id="creating_viewmodels">Creating a Viewmodel</h3>

				<p>First we'll create an empty Viewmodel in <code>APPPATH/view/index.php</code>:</p>

				<p class="note"><strong>Note:</strong> Viewmodels are located in <kbd>APPPATH/classes/view</kbd>. Views are located in <kbd>APPPATH/views</kbd>.</p>

				<pre><code>class View_Index extends Viewmodel {}</code></pre>

				<p>Then you create the view to which this belongs in <code>app/views/index.php</code>:</p>

				<pre><code>&lt;h1&gt;&lt;?php echo $title; ?&gt;&lt;/h1&gt;

&lt;ul&gt;
&lt;?php
	foreach ($articles as $a)
	{
		echo '&lt;li&gt;'.$a-&gt;title.'&lt;/li&gt;';
	}
?&gt;
&lt;/ul&gt;</code></pre>

				<p class="note"><strong>On view names</strong><br />
				A Viewmodel and its view are expected to share the same name. Thus a
				Viewmodel <code>View_Index</code> expects the view to be in <code>app/views/index.php</code>. And underscores
				work here the same as with classes, which means that the view for <code>View_Some_Thing</code> is expected
				to be in <code>app/views/some/thing.php</code>.<br />
				This default can be overwritten by setting a non-static <code>$_view</code> property in your Viewmodel with the
				View name (without .php suffix).</p>

				<p>And last we'll call the Viewmodel from the controller:</p>

				<pre class="php"><code>Viewmodel::forge('index');</code></pre>

				<p>Now we have everything setup; however, there is still no data passed to the view. It still needs to get a
				<code>$title</code> string and <code>$articles</code> array passed to it. We do this by adding a <code>view()</code> method
				to the Viewmodel which will assign this data:</p>

				<pre><code>class View_Index extends Viewmodel
{

	public function view()
	{
		$this->title = 'Testing this Viewmodel thing';

		$this->articles = Model_Articles::find('all');
	}
}</code></pre>

				<p>And you're done.</p>

				<h3 id="functions">Passing functions to views</h3>

				<p>To pass a View specific function from your Viewmodel to your View, you use <a href="http://www.php.net/manual/functions.anonymous.php">Closures</a>:</p>

				<pre class="php"><code>// In the Viewmodel
class View_Index extends Viewmodel
{

	public function view()
	{
		$this->echo_upper = function($string) { echo strtoupper($string); };
	}
}

// Which you can then use in your view:
$echo_upper('this string'); // Outputs: "THIS STRING"</code></pre>
			</article>

			<article>
				<h3 id="security">Security</h3>

				<p>It works the same as with View. This means that anything set on the Viewmodel will be output encoded as
					long as you don't switch that off. You can use the same <code>set($name, $value, $encode)</code> method
					on the Viewmodel as you'd use on the View directly. More on this in the
					<a href="views.html#security">Security section of View</a>.</p>
			</article>

			<article>
				<h3 id="advanced">Advanced usage</h3>

				<h4 id="more_methods">More methods</h4>

				<p>If there are different ways of parsing the same View, you can add multiple methods to the Viewmodel other
				than the default <code>view()</code> method. To use those, you need to add the method's name as the second parameter to the
				<code>Viewmodel::forge()</code> method:</p>

				<pre class="php"><code>// will call other_method() upon the Viewmodel from the above example
Viewmodel::forge('index', 'other_method');</code></pre>

				<h4 id="before_after">Before and after methods</h4>

				<p>If you need to have some data added for all the methods in the Viewmodel, you can add a <code>before()</code>
				or <code>after()</code> method just like you can with Controllers.</p>

				<h4 id="changing_view">Changing the view</h4>

				<p>By default, the <code>$this->_view</code> gets a View object assigned to it. You can replace this object by
				making your own <code>set_view()</code> method in the Viewmodel and setting the <code>$this->_view</code> to
				an object of your choosing.<br />
				However, this object must allow you to set properties on it (which are used as the template data) and must have
				a <code>__toString()</code> magic method that will render and return the parsed contents.<br />
				The name of the expected view is available in the <code>$this->_view</code> property.</p>

				<h4 id="alternative_view">Using a different view file, or an existing View object</h4>

				<p>You can also tell the Viewmodel instance to use a different view, and not use the automatic mechanism
				for determining the view to load, by using the forth parameter of the forge() method:</p>

				<pre class="php"><code>// use the 'other/index' view instead of the 'index' view
Viewmodel::forge('index', 'other_method', null, 'other/index');

// you can also pass a View object directly
$view = View::forge('other/index');
Viewmodel::forge('index', 'other_method', null, $view);</code></pre>

				<h4 id="access_to_view">Accessing the view</h4>
				<p>You can use the <code>get_view()</code> method to get access to the View object from outside the Viewmodel.</p>

				<h4>Using Viewmodels from other namespaces or not View_ prefixed</h4>

				<p>If you want to use these, you have to use the full classname with the <code>forge()</code>, including the namespace.
				In these cases, the default naming will often not work as expected so setting the <code>$_view</code>
				property, or passing a custom view name, is encouraged.</p>
			</article>

		</div>

		<footer>
			<p>
				&copy; FuelPHP Development Team 2010-2013 - <a href="http://fuelphp.com">FuelPHP</a> is released under the MIT license.
			</p>
		</footer>
	</div>
</body>
</html>
